# __HEADER__

"""XXX"""

import ldap.dn

class RDN(object):

    """XXX

    static

    Notes about order (can't determine order from kwargs, seems ok in openldap)
    """

    # Dictionary.
    # Value is always a string (unescaped).
    attributes = None
    value = ''

    def __init__(self, *args, **kwargs):
        attrs = self.attributes = {}

        for arg in args:
            parts = ldap.dn.str2dn(arg)
            if len(parts) != 1:
                raise ValueError('Argument %r for RDN is not valid.' % (arg,))
            for attr_name, attr_value, flag in parts[0]:
                if attr_name in attrs:
                    raise ValueError('Only one value per attribute allowed in RDN (attribute=%r)' % (attr_name,))
                attrs[attr_name] = attr_value

        for attr_name, attr_value in kwargs.items():
            if attr_name in attrs:
                raise ValueError('Only one value per attribute allowed in RDN (attribute=%r)' % (attr_name,))
            if isinstance(attr_value, (list, tuple)):
                if len(attr_value) != 1:
                    raise ValueError('Only one value per attribute allowed in RDN (attribute=%r)' % (attr_name,))
                attrs[attr_name] = attr_value[0]
            else:
                attrs[attr_name] = attr_value

        # Create a string version.
        pieces = []
        for attr_name, attr_value in attrs.items():
            pieces.append('%s=%s' % (attr_name, ldap.dn.escape_dn_chars(attr_value)))
        self.value = '+'.join(pieces)

    def __cmp__(self, other):
        if isinstance(other, RDN):
            # Values should be sorted to handle order-insensitive compare.
            return cmp(self.value, other.value)
        else:
            raise TypeError('Comparison of RDN with %s not supported.' % (type(other),))

class DN(object):

    """XXX

    DN(args)
    arg is:
      - RDN instance
      - string that is an RDN
      - DN string
    """

    rdn = None      # RDN instance
    parts = None    # list of RDN
    base = ''
    value = ''

    def __init__(self, *args):
        parts = []
        for arg in args:
            if isinstance(arg, RDN):
                parts.append(arg)
            else:
                for rdn in ldap.dn.str2dn(arg):
                    kw = {}
                    for attr_name, attr_value, flag in rdn:
                        l = kw.setdefault(attr_name, [])
                        l.append(attr_value)
                    parts.append(RDN(**kw))
        self.parts = parts
        self.rdn = self.parts[0]
        pieces = [rdn.value for rdn in self.parts[1:]]
        self.base = ','.join(pieces)
        self.value = self.rdn.value + ',' + self.base

    def __cmp__(self, other):
        if isinstance(other, DN):
            return cmp(self.value, other.value)
        else:
            raise TypeError('Comparison of DN with %s not supported.' % (type(other),))
